package com.gca.airhockey;

import android.app.Activity;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.ZoomCamera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnAreaTouchListener;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.Scene.ITouchArea;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.extension.input.touch.controller.MultiTouchController;
import org.anddev.andengine.extension.input.touch.exception.MultiTouchException;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.extension.physics.box2d.util.Vector2Pool;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.input.touch.detector.ScrollDetector;
import org.anddev.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener;
import org.anddev.andengine.input.touch.detector.SurfaceScrollDetector;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.sensor.accelerometer.AccelerometerData;
import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener;
import org.anddev.andengine.ui.activity.BaseGameActivity;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;

public class Main extends BaseGameActivity implements IOnSceneTouchListener,IScrollDetectorListener,
		IAccelerometerListener {
	// public class Main extends BaseGameActivity {

	// ===========================================================
	// Constants
	// ===========================================================
	static final int CAMERA_WIDTH = 1280;
	static final int CAMERA_HEIGHT = 752;

	// ===========================================================
	// Fields
	// ===========================================================
	private PhysicsWorld mPhysicsWorld;
	private SurfaceScrollDetector mScrollDetector;

	private Table mTable;
	private Puck mPuck;
	private Paddle mPaddle1;
	private Paddle mPaddle2;
	private Goal goalLeft;
	private Goal goalRight;

	private Wall ground;
	private Wall roof;
	private Wall left;
	private Wall right;

	// ===========================================================
	// Constructors
	// ===========================================================

	// ===========================================================
	// Getter &amp; Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	public void onLoadComplete() {
		// TODO Auto-generated method stub

	}

	@Override
	public Engine onLoadEngine() {
		final ZoomCamera camera = new ZoomCamera(0, 0, CAMERA_WIDTH,
				CAMERA_HEIGHT);

		final Engine engine = new Engine(new EngineOptions(true,
				ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(
						CAMERA_WIDTH, CAMERA_HEIGHT), camera));
		try {
			engine.setTouchController(new MultiTouchController());
		} catch (MultiTouchException e) {
			Toast.makeText(
					this,
					"Sorry your device does NOT support MultiTouch!\n\n(Falling back to SingleTouch.)",
					Toast.LENGTH_LONG).show();
		}
		return engine;
	}

	@Override
	public void onLoadResources() {
		mPhysicsWorld = new PhysicsWorld(new Vector2(0, 0), false);

		SoundManager.getInstance();
		SoundManager.initSounds(this);

		//Physical Objects
		mTable = new Table(this, mEngine);
		mPuck = new Puck(this, mEngine, mPhysicsWorld);
		mPaddle1 = new Paddle(this, mEngine, mPhysicsWorld, EColor.BLUE);
		mPaddle2 = new Paddle(this, mEngine, mPhysicsWorld, EColor.RED);
		goalLeft = new Goal(this, mEngine, mPhysicsWorld, ESide.LEFT);
		goalRight = new Goal(this, mEngine, mPhysicsWorld, ESide.RIGHT);
		ground = new Wall(this, mEngine, mPhysicsWorld,new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH,2));
		roof = new Wall(this, mEngine, mPhysicsWorld,new Rectangle(0, 0, CAMERA_WIDTH, 2));
		left = new Wall(this, mEngine, mPhysicsWorld,new Rectangle(0, 0, 2, CAMERA_HEIGHT));
		right = new Wall(this, mEngine, mPhysicsWorld,new Rectangle(CAMERA_WIDTH - 2, 0, 2, CAMERA_HEIGHT));
	}
 
	@Override
	public Scene onLoadScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());
		

		final Scene scene = new Scene(1);
		scene.attachChild(mTable.getSprite());
		scene.attachChild(mPuck.getSprite());
		scene.attachChild(mPaddle1.getSprite());
		scene.attachChild(mPaddle2.getSprite());
		scene.attachChild(goalLeft.getSprite());
		scene.attachChild(goalRight.getSprite());
		scene.attachChild(ground.getShape());
		scene.attachChild(roof.getShape());
		scene.attachChild(left.getShape());
		scene.attachChild(right.getShape());
		scene.registerUpdateHandler(this.mPhysicsWorld);
		scene.setOnSceneTouchListener(this);
		
		this.mScrollDetector = new SurfaceScrollDetector(this);
		this.mScrollDetector.setEnabled(true);
		
		this.enableAccelerometerSensor(this);

		return scene;
	}

	@Override
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
		this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
		
		int center = (int) (this.mPaddle1.getSprite().getWidth() / 2);

		if (pSceneTouchEvent.isActionDown() || pSceneTouchEvent.isActionMove()) {
			if (pSceneTouchEvent.getX() < 640) {
				this.mPaddle1.getBody().setType(BodyType.StaticBody);
				this.mPaddle1.getBody().setActive(true);
				this.mPaddle1.getSprite().setVisible(true);
				this.mPaddle1.getSprite().setPosition(
						pSceneTouchEvent.getX() - center,
						pSceneTouchEvent.getY() - center);
				this.mPaddle1.getBody().setTransform(
						new Vector2(pSceneTouchEvent.getX() / 32,
								pSceneTouchEvent.getY() / 32), 0);
			} else {
				this.mPaddle2.getBody().setType(BodyType.StaticBody);
				this.mPaddle2.getBody().setActive(true);
				this.mPaddle2.getSprite().setVisible(true);
				this.mPaddle2.getSprite().setPosition(
						pSceneTouchEvent.getX() - center,
						pSceneTouchEvent.getY() - center);
				this.mPaddle2.getBody().setTransform(
						new Vector2(pSceneTouchEvent.getX() / 32,
								pSceneTouchEvent.getY() / 32), 0);
			}
		} else if (pSceneTouchEvent.isActionUp()) {
		if (pSceneTouchEvent.getX() < 640) {
				this.mPaddle1.getBody().setType(BodyType.DynamicBody);
//				this.mPaddle1.getBody().setActive(false);
//				this.mPaddle1.getSprite().setVisible(false);
			} else {
				this.mPaddle2.getBody().setType(BodyType.DynamicBody);
//				this.mPaddle2.getBody().setActive(false);
//				this.mPaddle2.getSprite().setVisible(false);
			}
		}
		return true; 
	}

	@Override
	public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
		//final Vector2 gravity = Vector2Pool.obtain(pAccelerometerData.getX()*10, pAccelerometerData.getY()*10);
		//this.mPhysicsWorld.setGravity(gravity);
		//Vector2Pool.recycle(gravity);
	}

	@Override
	public void onScroll(ScrollDetector pScollDetector, TouchEvent pTouchEvent,float pDistanceX, float pDistanceY) {
			if (pTouchEvent.getX() < 640) {
				this.mPaddle1.setXDeplacement(pDistanceX);
				this.mPaddle1.setYDeplacement(pDistanceY);
				Log.v("APP", "Depalcement P2("+pDistanceX+","+pDistanceY+")");
			} else {
				this.mPaddle2.setXDeplacement(pDistanceX);
				this.mPaddle2.setYDeplacement(pDistanceY);
				Log.v("APP", "Depalcement P1("+pDistanceX+","+pDistanceY+")");
			}
	}

	// ===========================================================
	// Methods
	// ===========================================================

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}